#!/usr/bin/perl

use strict;

my $INTERPRETOR             = "/home/y/bin/php";
#my $SNAPSHOT_CREATOR        = "SnapshotCreator.php";
my $DATACONFUPDATESCRIPT    = "UpdateScConf.php";
my $DATACONFFILE            = "conf/scConf.json";
my $CONFIG_FILE	            = "scLoad.conf";

my $SC_CREATOR              = "ScCreator.php";

my $LIGHT_SC_LIST           = "scList/lightScList.json";
my $MEDIUM_SC_LIST          = "scList/mediumScList.json";
my $HEAVY_SC_LIST           = "scList/heavyScList.json";

my $SC_CREATOR_INST_COUNT; #= 4;
my $LIGHT_COUNT             ;#= 2; #num of parallel scripts for light
my $MEDIUM_COUNT            ;#= 1;  #num of parallel scripts for medium
my $HEAVY_COUNT             ;#= 1;  #num of parallel scripts for heavy

my $START_ID                = 0;
my $LIGHT_START_ID         ; #= 0;
my $MEDIUM_START_ID        ; #= 600000;
my $HEAVY_START_ID         ; #= 940000;
    
my $LIGHT_DIFF             ; #= 70; #num of users per script
my $MEDIUM_DIFF            ; #= 60; 
my $HEAVY_DIFF             ; #= 120;


my %confHash = ();

# Actual Flow start here ######################################################################################

my $user = `whoami`;

$user = strtrim($user);

if ( lc($user) ne "root" ) {
	print "You have to be root to execute this script\n";
	exit 1;
}


loadConfFile();



$SC_CREATOR_INST_COUNT = $confHash{'INSTANCE_COUNT'};
$LIGHT_COUNT             = $confHash{'LIGHT_COUNT'}; #num of parallel scripts for light
$MEDIUM_COUNT            = $confHash{'MEDIUM_COUNT'};  #num of parallel scripts for medium
$HEAVY_COUNT             = $confHash{'HEAVY_COUNT'};  #num of parallel scripts for heavy

$LIGHT_START_ID          = $confHash{'LIGHT_START'};
$MEDIUM_START_ID         = $confHash{'MEDIUM_START'};
$HEAVY_START_ID          = $confHash{'HEAVY_START'};
    
$LIGHT_DIFF              = $confHash{'LIGHT_DIFF'}; #num of users per script
$MEDIUM_DIFF             = $confHash{'MEDIUM_DIFF'}; 
$HEAVY_DIFF              = $confHash{'HEAVY_DIFF'};

#makeDataconfBackup();
#startAndMonitorScript($SNAPSHOT_CREATOR);

my $scripts = createInstancesForScript($SC_CREATOR, $SC_CREATOR_INST_COUNT);
#my $scripts = dummyCreateScript();
startAndMonitorMultipleScripts($scripts);

print("DONE!\n");




sub loadConfFile(){
  my $LOGFILE = $CONFIG_FILE;
  open(fh, $LOGFILE) or die("Cundt open data conf file\n");
  foreach my $line (<fh>){
     (my $varName, my $value) = split(' ',$line);
     $confHash{$varName} = $value;
  }
}


#starts and monitors multiple data load scripts: basically ScCreator

sub startAndMonitorMultipleScripts($) {
    my $scriptsref = shift;
    my @scripts    = @$scriptsref;

    while (1) {
        for ( my $i = 0 ; $i < scalar @scripts; $i++ ) {
            my $scriptname      = $scripts[$i]->{"sn"};
            my $outputfile      = $scripts[$i]->{"of"};
            my $statusfile      = $scripts[$i]->{"sf"};
            my $dataconffile    = $scripts[$i]->{"df"};
           
            my $result = isScriptRunning($scriptname);
            if ( $result == 0 ) {
                print("$scriptname running\n");
                next;
            } else { 
                print("Script $scriptname not running\n");
            }

            $result = checkScriptStatusFile($statusfile);
            if ( $result == 0 ) {
                print("**** $scriptname is completed *****\n");
                next;
            }
 
            print("Cleaning log files \n");
            cleanLogFiles();                   
            
            $result = startScript( $scriptname, $dataconffile, $outputfile );
             if ( $result != 0 ) {
                print("Error in starting $scriptname\n");
                exit(1);
             }

            print("I have started $scriptname \n");
            
        }
      #}
        sleep(10);
    }
}



#makes replicas of the conv creator script
sub createInstancesForScript(@) {
    my $scriptname  = shift;
    my $numInstance = shift;
    #my $startId     = shift;
    my $difference  = 0;
    my $index          = 0;

    my $ext      = $scriptname;
    my $dataconf = $DATACONFFILE;
    my $dcext    = $dataconf;

    $scriptname =~ s/(.*)\.(.*)/$1/;
    $ext        =~ s/(.*)\.(.*)/$2/;
    $dataconf   =~ s/(.*)\.(.*)/$1/;
    $dcext      =~ s/(.*)\.(.*)/$2/;

    my @scripts = ();
    for ( my $i = 0 ; $i < $numInstance ; $i++ ) {
 
      	if (0 != copyFile($scriptname . "." . $ext, $scriptname . ( $i + 1 ) . "." . $ext)) {
       	     print("Error in creating instances of script\n");
       	     exit(1);
       	}

        my $confFileName = "";
        my $startId = 0;
        my $scFileName = "";
        
        if($i < $LIGHT_COUNT){
            $confFileName = $dataconf. "Light." . $dcext;
            $startId = $LIGHT_START_ID;
            $difference = $LIGHT_DIFF;
            $scFileName = $LIGHT_SC_LIST;
            
            $index = $startId + $i*$difference;
        }
        elsif($i >= $LIGHT_COUNT && $i < ($LIGHT_COUNT + $MEDIUM_COUNT)){
            $confFileName = $dataconf. "Medium.". $dcext;
            $startId = $MEDIUM_START_ID;
            $difference = $MEDIUM_DIFF;
            $scFileName = $MEDIUM_SC_LIST;
            
            $index = $startId + ($i-$LIGHT_COUNT)*$difference;
        }
        else{
             $confFileName = $dataconf. "Heavy.". $dcext;
             $startId = $HEAVY_START_ID;
             $difference = $HEAVY_DIFF;   
             $scFileName = $HEAVY_SC_LIST;
            
             $index = $startId + ($i-$MEDIUM_COUNT-$LIGHT_COUNT)*$difference;
        }
    
        my $newFileName = $dataconf . ( $i + 1 ) . "." . $dcext;

        if (0 != copyFile($confFileName, $newFileName)) {
                print("Error in creating instances of script\n");
                exit(1);
        }

        my %script = {};
        $script{"sn"} = $scriptname . ( $i + 1 ) . "." . $ext;
        $script{"of"} = $scriptname . ( $i + 1 ) . ".out";
        $script{"sf"} = $scriptname . ( $i + 1 ) . ".status";
        $script{"df"} = $newFileName;
        $scripts[$i]  = \%script;

 
        #my $id = $i * $difference + $startId;
        my $result = system("$INTERPRETOR $DATACONFUPDATESCRIPT $scripts[$i]->{\"df\"} $scFileName $index >/dev/null 2>>error");
       
        if ( $result != 0 ) {
                print("Error in updating sc_id for $scripts[$i]->{\"sn\"}\n");
                exit(1);
        }
        
    }

    return \@scripts;
}




sub dummyCreateScript(){

 my @scripts = ();
 for(my $i=0;$i<10;$i++){

   my %script = {};
   my $scriptName = "ScCreator";  
   my $fileName = "conf/scConf";

   $script{"sn"} = $scriptName . ( $i + 1 ) . ".php";
   $script{"of"} = $scriptName . ( $i + 1 ) . ".out";
   $script{"sf"} = $scriptName . ( $i + 1 ) . ".status";
   $script{"df"} = $fileName   . ( $i + 1 ) . ".json";
   $scripts[$i]  = \%script;
 }
 
  return \@scripts;
}



#copies a file
sub copyFile($) {
    my $source = shift;
    my $dest   = shift;
    my $result = system("/bin/cp -f $source $dest >/dev/null 2>>error");
    if ( $result != 0 ) {
        print("Error in copying file $source to $dest\n");
        return 1;
    }

    return 0;
}



#empties a status file
sub cleanScriptStatusFile($) {
    my $filename = shift;
    open( FILE, ">$filename" ) or die("Error in opening $filename\n");
    print FILE ("") or die("Error in writing to $filename\n");
    close(FILE) or die("Error in closing $filename\n");
    return 0;
}



#starts running a script
sub startScript($) {
    my $scriptname = shift;
    my $conffile = shift;
    my $outputfile = shift;

    my $result     = system("$INTERPRETOR $scriptname $conffile > $outputfile 2>&1 &");
    if ( $result != 0 ) {
        print("Error in starting $scriptname.php\n");
        exit(1);
    }

    return 0;
}



#checks if a script is running or not
sub isScriptRunning($) {
    my $scriptname = shift;
    #print("Script running test command: ps -ef | grep \"$scriptname\" | grep -v \"grep\" > /dev/null 2>>error\n");
    return
      system("ps -ef | grep \"$scriptname\" | grep -v \"grep\" > /dev/null 2>>error");
}




#checks the status of the script 
sub checkScriptStatusFile($) {
    my $filename = shift;
    if( ! -r $filename) {
        return 1;    
    }
    
    open( FILE, "<$filename" ) or die("Error in opening $filename\n");
    my $line;
    while (<FILE>) {
        $line = $_;
        if ( strtrim($line) eq "DONE" ) {
            close(FILE) or die("Error in closing $filename\n");
            return 0;
        }
    }

    return 1;
}



sub makeDataconfBackup() {
    my $result = system("/bin/cp -f $DATACONFFILE $DATACONFFILE.bak");
    if ( $result != 0 ) {
        print("Error in making a copy of original dataconf file\n");
        exit(1);
    }
    return 0;
}


# this function is used for cleaning the log files which make the script crash
# if the file size exceeds 2 GB.
sub cleanLogFiles($){
   
   my $result = system("> /home/piyush/logs/apache.log");
   if ( $result != 0 ) {
        print("Error: Could not clear the apache log file\n");
    }

   $result = system("> /home/piyushg/logs/commoncpp.log");
   if ( $result != 0 ) {
        print("Error: Could not clear the commoncpp log file\n");
    }


   $result = system("> /home/piyushg/logs/dbconnection.log");
   if ( $result != 0 ) {
        print("Error: Could not clear the dbconnectionlog file\n");
    }
 
   $result = system("> /home/piyushg/logs/conv.log");
   if ( $result != 0 ) {
        print("Error: Could not clear the conversation log file\n");
    }
     
   return;   
}



sub updateDataconfFile($) {
    my $filename = shift;
    my $numUsers = shift;
    print("Dataconf update command: $INTERPRETOR $DATACONFUPDATESCRIPT users $numUsers $filename\n");
    my $result   =
      system("$INTERPRETOR $DATACONFUPDATESCRIPT users $numUsers $filename");
    if ( $result != 0 ) {
        print("Error in updating dataconf file\n");
    }

    return $result;
}



sub strtrim($) {
    my $string = shift;
    $string =~ s/^\s+//;
    $string =~ s/\s+$//;
    return $string;
}



# Left trim function to remove leading whitespace
sub strltrim($) {
    my $string = shift;
    $string =~ s/^\s+//;
    return $string;
}



#Right trim function to remove trailing whitespace
sub strrtrim($) {
    my $string = shift;
    $string =~ s/\s+$//;
    return $string;
}

